﻿using System;
using System.Linq;
using iTeamyou.LTS.Core.Models;
using iTeamyou.LTS.Core.Utils;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace iTeamyou.LTS.Core.Services
{
	public class SupplierService : IDataService<Supplier, SupplierLicense>
	{
        public MainDBContext _dbContext;
        private readonly ILogger<Supplier> _logger;
        private Comparator _comparator;
        private SupplierAttachmentService _attachmentService;
        public SharedService _sharedService = new SharedService();

        public SupplierService()
        {
            _dbContext ??= new MainDBContext();
        }

        public SupplierService(string connectionString)
        {
            _dbContext = new MainDBContext(new DbContextOptionsBuilder<MainDBContext>().UseMySql(connectionString, new MySqlServerVersion(new Version())).Options);
        }

        public SupplierService(MainDBContext dbContext, ILogger<Supplier> logger, SupplierAttachmentService attachmentService)
		{
            _dbContext = dbContext;
            _logger = logger;
            _comparator = new Comparator();
            _attachmentService = attachmentService;
        }

        public int Delete(IEnumerable<Supplier> suppliers)
        {
            _dbContext.Suppliers.RemoveRange(suppliers);
            return _dbContext.SaveChanges();
        }

        public Supplier Get(string id)
        {
            return _dbContext.Suppliers.AsNoTracking().FirstOrDefault(s => s.Id == id);
        }

        public List<Supplier> GetByCode(string sid)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => s.SId == sid).ToList();
        }
        //新增批量查询
        public List<Supplier> GetByCodes(IEnumerable<string> sids)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => sids.Contains(s.SId)).ToList();
        }

        public List<Supplier> GetByRefId(string refId)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => s.RefId == refId).ToList();
        }

        //新增批量查询
        public List<Supplier> GetByRefIds(List<string> refIds)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => refIds.Contains(s.RefId)).ToList();
        }

        public List<Supplier> GetByName(string name)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => s.Name == name).ToList();
        }
        //新增批量查询
        public List<Supplier> GetByNames(IEnumerable<string> names)
        {
            return _dbContext.Suppliers.AsNoTracking().Where(s => names.Contains(s.Name)) .ToList();
        }

        public SupplierLicense GetLicenseByLId(string lid)
        {
            return _dbContext.SupplierLicenses.AsNoTracking().Where(s => s.LId == lid).FirstOrDefault();
        }

        public int GetLicenseCount()
        {
            return _dbContext.SupplierLicenses.Count(l => l.IsPublish == true);
        }

        public List<Supplier> GetList()
        {
            var list = _dbContext.Suppliers.AsNoTracking().OrderByDescending(s => s.LastModifiedOn).ToList();
            //if (list.Count > 0)
            //{
            //    foreach(var supplier in list)
            //    {
            //        supplier.SupplierLicenses = GetLicensesById(supplier.Id);
            //    }
            //}

            return list;
        }

        public List<ExportSupplier> GetExport()
        {
            var result = new List<ExportSupplier>();
            var list = _dbContext.Suppliers.AsNoTracking().OrderByDescending(s => s.LastModifiedOn).ToList();
            if (list.Count > 0)
            {
                foreach (var supplier in list)
                {
                    var export = new ExportSupplier()
                    {
                        Contact = supplier.Contact,
                        ContactNumber = supplier.ContactNumber,
                        CreatedBy = supplier.CreatedBy,
                        CreatedOn = supplier.CreatedOn,
                        Id = supplier.SId,
                        LastModifiedOn = supplier.LastModifiedOn,
                        Name = supplier.Name,
                        Region = supplier.Region,
                        Status = supplier.Status
                    };

                    var licenses = GetLicensesById(supplier.Id);
                    var urlList = new List<string>();
                    if (licenses.Count > 0)
                    {
                        foreach (var license in licenses)
                        {
                            var attachment = _attachmentService.GetList(license.Id, true).FirstOrDefault();
                            if (attachment != null)
                                urlList.Add(attachment.URL);
                            var otherAttachment = _attachmentService.GetList(license.Id, false);
                            if (otherAttachment != null && otherAttachment.Any())
                                otherAttachment.ForEach(o => urlList.Add(o.URL));
                        }
                    }
                    export.SupplierLicenseUrl = urlList;
                    result.Add(export);
                }
            }
            return result;
        }

        public List<ExportSupplier> GetExport(List<Supplier> suppliers)
        {
            var result = new List<ExportSupplier>();
            if (suppliers.Count > 0)
            {
                foreach (var supplier in suppliers)
                {
                    var export = new ExportSupplier()
                    {
                        Contact = supplier.Contact,
                        ContactNumber = supplier.ContactNumber,
                        CreatedBy = supplier.CreatedBy,
                        CreatedOn = supplier.CreatedOn,
                        Id = supplier.SId,
                        LastModifiedOn = supplier.LastModifiedOn,
                        Name = supplier.Name,
                        Region = supplier.Region,
                        Status = supplier.Status
                    };

                    var licenses = GetLicensesById(supplier.Id);
                    var urlList = new List<string>();
                    if (licenses.Count > 0)
                    {
                        foreach (var license in licenses)
                        {
                            var attachment = _attachmentService.GetList(license.Id, true).FirstOrDefault();
                            if (attachment != null)
                                urlList.Add(attachment.URL);
                            var otherAttachment = _attachmentService.GetList(license.Id, false);
                            if (otherAttachment != null && otherAttachment.Any())
                                otherAttachment.ForEach(o => urlList.Add(o.URL));
                        }
                    }
                    export.SupplierLicenseUrl = urlList;
                    result.Add(export);
                }
            }
            return result;
        }

        public void Save(Supplier supplier)
        {
            var exists = _dbContext.Suppliers.Where(g => g.Id == supplier.Id).FirstOrDefault();
            if (exists == null)
            {
                if (supplier.CreatedOn == null)
                    supplier.CreatedOn = DateTime.Now;
                _dbContext.Add(supplier);
            }
            else
            {
                exists.Contact = supplier.Contact;
                exists.ContactNumber = supplier.ContactNumber;
                exists.LastModifiedBy = supplier.LastModifiedBy;
                exists.LastModifiedOn = supplier.LastModifiedOn;
                exists.Name = supplier.Name;
                exists.Region = supplier.Region;
                exists.Status = supplier.Status;
                exists.SId = supplier.SId;
                //exists.SupplierLicenses = supplier.SupplierLicenses;
                //if (supplier.SupplierLicenses != null && supplier.SupplierLicenses.Count() > 0)
                exists.LicenseNum = _dbContext.SupplierLicenses.Where(s => s.SupplierId == supplier.Id && s.IsPublish == true).Count();
                //SaveLicense(supplier.Id, supplier.SupplierLicenses, supplier.LastModifiedBy);
                exists.SupplierLicenses = supplier.SupplierLicenses;
                SaveLicense(exists);
            }
            _dbContext.SaveChanges();
        }
        //新增批量保存
        public void BatchSave(List<Supplier> suppliersToAdd)
        {
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 开始批量新增，共 {suppliersToAdd.Count} 条供应商数据。");
            if (suppliersToAdd == null || !suppliersToAdd.Any())
            {
                return;
            }

            // 获取所有需要更新的Supplier Ids
            var supplierIds = suppliersToAdd.Select(s => s.Id).Distinct().ToList();

            // 一次性加载所有存在的Supplier实体
            var existingSuppliers = _dbContext.Suppliers.Where(s => supplierIds.Contains(s.Id)).ToDictionary(s => s.Id, s => s);

            foreach (var supplier in suppliersToAdd)
            {
                if (!existingSuppliers.ContainsKey(supplier.Id))
                {
                    if (supplier.CreatedOn == null)
                        supplier.CreatedOn = DateTime.Now;
                    _dbContext.Add(supplier);
                }
                else
                {
                    var exists = existingSuppliers[supplier.Id];
                    exists.Contact = supplier.Contact;
                    exists.ContactNumber = supplier.ContactNumber;
                    exists.LastModifiedBy = supplier.LastModifiedBy;
                    exists.LastModifiedOn = supplier.LastModifiedOn;
                    exists.Name = supplier.Name;
                    exists.Region = supplier.Region;
                    exists.Status = supplier.Status;
                    exists.SId = supplier.SId;
                    exists.LicenseNum = _dbContext.SupplierLicenses.Where(sl => sl.SupplierId == supplier.Id && sl.IsPublish == true).Count();
                    exists.SupplierLicenses = supplier.SupplierLicenses;
                    SaveLicense(exists);
                }
            }
            _dbContext.SaveChanges();
        }

        public void Update(Supplier supplier)
        {
            var exist = _dbContext.Suppliers.Where(g => g.Id == supplier.Id).FirstOrDefault();
            if (exist == null)
                return;

            exist.SId = supplier.SId;
            exist.RefId = supplier.RefId;
            exist.Name = supplier.Name;
            exist.Contact = supplier.Contact;
            exist.Status = supplier.Status;
            exist.ContactNumber = supplier.ContactNumber;
            exist.LastModifiedBy = supplier.LastModifiedBy;
            exist.LastModifiedOn = supplier.LastModifiedOn;
            _dbContext.SaveChanges();
        }

        //新增批量修改方法
        public void BatchUpdate(IEnumerable<Supplier> suppliersToUpdate)
        {
            Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 开始批量更新，共 {suppliersToUpdate.Count()} 条供应商数据。");
            // 提取所有需要更新的Supplier的ID
            var ids = suppliersToUpdate.Select(s => s.Id).ToList();

            // 查询所有对应的实体
            var existSuppliers = _dbContext.Suppliers.Where(s => ids.Contains(s.Id)).ToList();

            // 转换成字典，方便快速匹配
            var supplierDict = suppliersToUpdate.ToDictionary(s => s.Id);

            foreach (var existSupplier in existSuppliers)
            {
                if (supplierDict.TryGetValue(existSupplier.Id, out var updateSupplier))
                {
                    // 更新字段
                    existSupplier.SId = updateSupplier.SId;
                    existSupplier.RefId = updateSupplier.RefId;
                    existSupplier.Name = updateSupplier.Name;
                    existSupplier.Contact = updateSupplier.Contact;
                    existSupplier.Status = updateSupplier.Status;
                    existSupplier.ContactNumber = updateSupplier.ContactNumber;
                    existSupplier.LastModifiedBy = updateSupplier.LastModifiedBy;
                    existSupplier.LastModifiedOn = updateSupplier.LastModifiedOn;
                }
            }

            // 提交所有更新
            _dbContext.SaveChanges();
        }

        public List<SupplierLicense> GetLicenses(List<SupplierLicense>? licenses = null)
        {
            var result = new List<SupplierLicense>();
            if (licenses != null && licenses.Any())
                result = licenses;
            else
                result = _dbContext.SupplierLicenses.AsNoTracking().Where(l => l.IsPublish == true).ToList();

            foreach (var license in result)
            {
                if (license.ValidToDate != null)
                    license.RemainingDays = ((DateTime)license.ValidToDate - DateTime.Now).Days;

                //var attachment = _attachmentService.GetList(license.Id, true).FirstOrDefault();
                //var licenseList = new List<string>();
                //if (attachment != null)
                //    licenseList.Add(attachment.URL);
                //var otherAttachment = _attachmentService.GetList(license.Id, false);
                //if (otherAttachment != null && otherAttachment.Any())
                //    otherAttachment.ForEach(o => licenseList.Add(o.URL));

                //license.AttachmentURL = licenseList;
            }
            return result;
        }

        public List<SupplierLicense> GetLicensesExport(List<SupplierLicense>? licenses = null)
        {
            var result = new List<SupplierLicense>();
            if (licenses != null && licenses.Any())
                result = licenses;
            else
                result = _dbContext.SupplierLicenses.AsNoTracking().Where(l => l.IsPublish == true).ToList();

            foreach (var license in result)
            {
                if (license.ValidToDate != null)
                    license.RemainingDays = ((DateTime)license.ValidToDate - DateTime.Now).Days;

                var attachment = _attachmentService.GetList(license.Id, true).FirstOrDefault();
                var licenseList = new List<string>();
                if (attachment != null)
                    licenseList.Add(attachment.URL);
                var otherAttachment = _attachmentService.GetList(license.Id, false);
                if (otherAttachment != null && otherAttachment.Any())
                    otherAttachment.ForEach(o => licenseList.Add(o.URL));

                license.AttachmentURL = licenseList;
            }
            return result;
        }

        public List<SupplierLicense> GetLicensesById(string sid)
        {
            return _dbContext.SupplierLicenses.AsNoTracking().Where(s => s.SupplierId == sid && s.IsPublish == true).ToList();
        }

        public List<LicenseType> GetLicenseType(string type = "")
        {
            if (string.IsNullOrEmpty(type))
                return _dbContext.LicenseTypes.AsNoTracking().ToList();
            return _dbContext.LicenseTypes.AsNoTracking().Where(l => l.Module == type).ToList();
        }

        private void SaveLicense(Supplier supplier)
        {
            var licenses = supplier.SupplierLicenses;
            var id = supplier.Id;
            var userId = supplier.LastModifiedBy;

            var exists = _dbContext.SupplierLicenses.AsNoTracking().Where(s => s.SupplierId == id && s.IsPublish == true).OrderBy(s => s.Id).ToList();
            var licensesCompare = licenses.OrderBy(l => l.Id).ToList();
            if (_comparator.DifferenceComparison(exists, licensesCompare))
            {
                //发起流程
                var currentTbId = "fd_3c7343ed25a0e8";
                var historyTbId = "fd_3c7344bbcb4a6c";
                var flowService = new EKPFlowService();
                var formValues = new string("{\"fd_3c73440309699e\":\"" + supplier.Name + "\", \"fd_3c734404052200\":\"" + supplier.SId + "\",");
                var tbValue1 = $"\"{currentTbId}.fd_3c7344a1863166\":[";
                var tbValue2 = $"\"{currentTbId}.fd_3c7491d44ed0da\":[";
                var tbValue3 = $"\"{currentTbId}.fd_3c7491d84aabe6\":[";
                var tbValue4 = $"\"{currentTbId}.fd_3c7344a53921c2\":[";
                var tbValue5 = $"\"{currentTbId}.fd_3c7344a7ced6b2\":[";
                var tbValue6 = $"\"{currentTbId}.fd_3c7344a67ef9e8\":[";

                var tbHistoryValue1 = $"\"{historyTbId}.fd_3c7344e5124b46\":[";
                var tbHistoryValue2 = $"\"{historyTbId}.fd_3c749202cd5272\":[";
                var tbHistoryValue3 = $"\"{historyTbId}.fd_3c749204297b04\":[";
                var tbHistoryValue4 = $"\"{historyTbId}.fd_3c7344e8f4f4b6\":[";
                var tbHistoryValue5 = $"\"{historyTbId}.fd_3c7344ea331368\":[";

                if (exists != null && exists.Any())
                {
                    exists.ForEach(e =>
                    {
                        var attachmentURL = string.Empty;
                        var attachment = e.Attachments?.FirstOrDefault(l => l.IsMain == true);
                        if (attachment != null)
                            attachmentURL = attachment.URL;

                        tbHistoryValue1 += "\"" + GetLicenseTypeName(e.Type, "supplier") + "\",";
                        tbHistoryValue2 += "\"" + ((DateTime)e.ValidFromDate).ToString("yyyy-MM-dd") + "\",";
                        tbHistoryValue3 += "\"" + ((DateTime)e.ValidToDate).ToString("yyyy-MM-dd") + "\",";
                        tbHistoryValue4 += "\"" + e.LId + "\",";
                        tbHistoryValue5 += "\"" + attachmentURL + "\",";
                    });

                    tbHistoryValue1 = tbHistoryValue1.Remove(tbHistoryValue1.LastIndexOf(","), 1) + "],";
                    tbHistoryValue2 = tbHistoryValue2.Remove(tbHistoryValue2.LastIndexOf(","), 1) + "],";
                    tbHistoryValue3 = tbHistoryValue3.Remove(tbHistoryValue3.LastIndexOf(","), 1) + "],";
                    tbHistoryValue4 = tbHistoryValue4.Remove(tbHistoryValue4.LastIndexOf(","), 1) + "],";
                    tbHistoryValue5 = tbHistoryValue5.Remove(tbHistoryValue5.LastIndexOf(","), 1) + "],";
                    formValues += tbHistoryValue1 + tbHistoryValue2 + tbHistoryValue3 + tbHistoryValue4 + tbHistoryValue5;
                }

                if (licenses != null && licenses.Any())
                {
                    licenses.ForEach(license =>
                    {
                        var existLicense = exists.FirstOrDefault(l => l.Id == license.Id);
                        if (string.IsNullOrEmpty(license.Id) || _comparator.DifferenceEntityComparison(existLicense, license))
                        {
                            if (exists.Any(e => e.Id == license.Id) && license.OperationType != LicenseOp.Delete)
                                license.OperationType = LicenseOp.Modify;
                            else if (license.OperationType != LicenseOp.Delete)
                                license.OperationType = LicenseOp.Add;

                            if (string.IsNullOrEmpty(license.CreatedBy))
                                license.CreatedBy = userId;

                            license.Id = Guid.NewGuid().ToString("N");
                            license.IsPublish = false;

                            license.Attachments?.ForEach(a =>
                            {
                                a.Id = Guid.NewGuid().ToString("N");
                                a.LicenseId = license.Id;
                                _dbContext.SupplierLicenseAttachments.Add(a);
                            });

                            var opTypeString = "";
                            if (license.OperationType == LicenseOp.Add)
                                opTypeString = "新增";
                            else if (license.OperationType == LicenseOp.Modify)
                                opTypeString = "修改";
                            else if (license.OperationType == LicenseOp.Delete)
                                opTypeString = "删除";

                            var attachmentURL = string.Empty;
                            var attachment = license.Attachments?.FirstOrDefault(l => l.IsMain == true);
                            if (attachment != null)
                                attachmentURL = attachment.URL;

                            tbValue1 += "\"" + GetLicenseTypeName(license.Type, "supplier") + "\",";
                            tbValue2 += "\"" + ((DateTime)license.ValidFromDate).ToString("yyyy-MM-dd") + "\",";
                            tbValue3 += "\"" + ((DateTime)license.ValidToDate).ToString("yyyy-MM-dd") + "\",";
                            tbValue4 += "\"" + license.LId + "\",";
                            tbValue5 += "\"" + opTypeString + "\",";
                            tbValue6 += "\"" + attachmentURL + "\",";

                            license.Attachments = new List<SupplierLicenseAttachment>();
                        }
                    });

                    tbValue1 = tbValue1.Remove(tbValue1.LastIndexOf(","), 1) + "],";
                    tbValue2 = tbValue2.Remove(tbValue2.LastIndexOf(","), 1) + "],";
                    tbValue3 = tbValue3.Remove(tbValue3.LastIndexOf(","), 1) + "],";
                    tbValue4 = tbValue4.Remove(tbValue4.LastIndexOf(","), 1) + "],";
                    tbValue5 = tbValue5.Remove(tbValue5.LastIndexOf(","), 1) + "],";
                    tbValue6 = tbValue6.Remove(tbValue6.LastIndexOf(","), 1) + "]";
                    formValues += tbValue1 + tbValue2 + tbValue3 + tbValue4 + tbValue5 + tbValue6 + "}";
                    var flowId = flowService.AddReview(_sharedService.GetConfig("EKPSupplierLicenseTemplateId"), "供应商证照更新", userId, formValues);

                    licenses.ForEach(l => l.RefFlowId = flowId);
                    _dbContext.SupplierLicenses.AddRange(licenses);
                }
                //else //todo: 观察
                //    _dbContext.ProductLicenses.RemoveRange(exists);

                _dbContext.SaveChanges();
            }
        }
        //private void SaveLicense(string id, List<SupplierLicense> licenses, string userId)
        //{
        //    var exists = _dbContext.SupplierLicenses.Where(s => s.SupplierId == id && s.IsPublish == true);
        //    if (_comparator.DifferenceComparison(exists.OrderBy(e => e.Id).ToList(), licenses.OrderBy(l => l.Id).ToList()))
        //    {
        //        if (licenses != null && licenses.Count > 0)
        //        {
        //            //发起流程
        //            var flowService = new EKPFlowService();
        //            var flowId = flowService.AddReview(_sharedService.GetConfig("EKPSupplierLicenseTemplateId"), "供应商证照更新", userId);

        //            licenses.ForEach(l =>
        //            {
        //                if (string.IsNullOrEmpty(l.CreatedBy))
        //                    l.CreatedBy = userId;

        //                l.Id = Guid.NewGuid().ToString("N");
        //                l.IsPublish = false;
        //                l.RefFlowId = flowId;

        //                if (l.Attachments != null)
        //                {
        //                    l.Attachments.ForEach(a =>
        //                    {
        //                        a.Id = Guid.NewGuid().ToString("N");
        //                        a.LicenseId = l.Id;
        //                        _dbContext.SupplierLicenseAttachments.Add(a);
        //                    });
        //                    l.Attachments = new List<SupplierLicenseAttachment>();
        //                }

        //                if (exists.Any(e => e.Id == l.Id) && l.OperationType != LicenseOp.Delete)
        //                    l.OperationType = LicenseOp.Modify;
        //                else if (l.OperationType != LicenseOp.Delete)
        //                    l.OperationType = LicenseOp.Add;
        //            });

        //            _dbContext.SupplierLicenses.AddRange(licenses);
        //        }
        //        //else
        //        //    _dbContext.SupplierLicenses.RemoveRange(exists);

        //        _dbContext.SaveChanges();
        //    }
        //}

        public void UploadLicense(SupplierLicense license)
        {
            _dbContext.SupplierLicenses.Add(license);
            _dbContext.SaveChanges();
        }

        public void LicenseStatistics()
        {
            var suppliers = GetList();
            if (suppliers.Any())
            {
                foreach (var supplier in suppliers)
                {
                    var licenses = GetLicensesById(supplier.Id);
                    if (licenses.Any())
                    {
                        var update = _dbContext.Suppliers.Where(p => p.Id == supplier.Id).FirstOrDefault();
                        update.LicenseNum = licenses.Count();
                        _dbContext.SaveChanges();
                    }
                }
            }
        }

        private string GetLicenseTypeName(string id, string module)
        {
            var licenseTypes = GetLicenseType();
            if (licenseTypes != null && licenseTypes.Any())
            {
                var licenseType = licenseTypes.FirstOrDefault(predicate: l => l.TypeId == id && l.Module == module);
                if (licenseType != null)
                    return licenseType.TypeName;
            }
            return string.Empty;
        }
    }
}

